<script setup lang="ts">
import { onMounted, ref } from 'vue'
import {
  initDemo,
  createImageIdsAndCacheMetaData
} from '@/helpers'
import {
  cache, Enums, RenderingEngine, setVolumesForViewports, Types, volumeLoader
} from '@cornerstonejs/core'

const { ViewportType, RequestType } = Enums
import cornerstoneDICOMImageLoader from '@cornerstonejs/dicom-image-loader'
import * as cornerstoneTools from '@cornerstonejs/tools'
import { PACS } from '@/config/config'

const {
  PanTool,
  ZoomTool,
  StackScrollMouseWheelTool,
  CrosshairsTool,
  ToolGroupManager,
  Enums: csToolsEnums,
  utilities: csToolsUtilities
} = cornerstoneTools
const { MouseBindings } = csToolsEnums

let renderingEngines = []
let volumes = []
const seriesCount = 10

function initViewports() {
  // Instantiate a rendering engine
  const viewportInputArray = [
    {
      viewportId: viewportIds[0],
      type: ViewportType.ORTHOGRAPHIC,
      element: axRef.value![0],
      defaultOptions: {
        background: <Types.Point3>[0.2, 0, 0.2]
      }
    },
    {
      viewportId: viewportIds[1],
      type: ViewportType.ORTHOGRAPHIC,
      element: sagRef.value![0],
      defaultOptions: {
        orientation: Enums.OrientationAxis.CORONAL,
        background: <Types.Point3>[0.2, 0, 0.2]
      }
    },
    {
      viewportId: viewportIds[2],
      type: ViewportType.ORTHOGRAPHIC,
      element: corRef.value![0],
      defaultOptions: {
        orientation: Enums.OrientationAxis.SAGITTAL,
        background: <Types.Point3>[0.2, 0, 0.2]
      }
    }
  ]

  for (let i = 0; i < seriesCount; i++) {
    const id = `renderingEngineId-${i}`
    const renderingEngine = new RenderingEngine(id)
    const { volumeId } = volumes[i]
    renderingEngine.setViewports(viewportInputArray)
    renderingEngines.push(renderingEngine)
    // Set volumes on the viewports
    setVolumesForViewports(
      renderingEngine,
      [{ volumeId }],
      viewportIds
    )
  }
}

async function createVolume(): any {
  const seriesIds = [
    '1.2.392.200036.9107.307.31909.120240301.1102826.142329',
    '1.2.2046.7929.09.1.20240301.103311.10920',
    '1.2.2046.7929.09.1.20240301.103359.25746',
    '1.2.2046.7929.09.1.20240301.103447.93095',
    '1.2.2046.7929.09.1.20240301.103535.17768',
    '1.2.2046.7929.09.1.20240301.103624.79468',
    '1.2.2046.7929.09.1.20240301.103712.23891',
    '1.2.2046.7929.09.1.20240301.103800.93438',
    '1.2.2046.7929.09.1.20240301.103848.91571',
    '1.2.2046.7929.09.1.20240301.103937.38151'
  ]
  for (let i = 0; i < seriesCount; i++) {
    const params = {
      StudyInstanceUID:
        '1.2.392.200036.9107.307.31909.120240301.1102826.123575',
      SeriesInstanceUID: seriesIds[i],
      wadoRsRoot: PACS.root + '/dicom-web'
    }
    let imageIds = await createImageIdsAndCacheMetaData(params)
    const volumeId = `volumeId-${i}`
    const volume = await volumeLoader.createAndCacheVolume(volumeId, {
      imageIds
    })
    volumes.push(volume)
  }

}

const sagRef = ref(null)
const axRef = ref(null)
const corRef = ref(null)

const viewportId1 = 'Axial'
const viewportId2 = 'Sagittal'
const viewportId3 = 'Coronal'

const viewportIds = [viewportId1, viewportId2, viewportId3]
const renderingEngineId = 'renderingEngineId'
const views = [
  {
    'ref': axRef,
    'class': 'lt',
    'viewportId': viewportId1
  },
  {
    'ref': sagRef,
    'class': 'lb',
    'viewportId': viewportId2
  },
  {
    'ref': corRef,
    'class': 'rt',
    'viewportId': viewportId3
  }
]

const viewportColors = {
  [viewportIds[0]]: 'rgb(200, 0, 0)',
  [viewportIds[1]]: 'rgb(200, 200, 0)',
  [viewportIds[2]]: 'rgb(0, 200, 0)'
}

const viewportReferenceLineControllable = viewportIds.slice()
const viewportReferenceLineDraggableRotatable = viewportIds.slice()
const viewportReferenceLineSlabThicknessControlsOn = viewportIds.slice()

function getReferenceLineColor(viewportId) {
  return viewportColors[viewportId]
}

function getReferenceLineControllable(viewportId) {
  return viewportReferenceLineControllable.includes(viewportId)
}

function getReferenceLineDraggableRotatable(viewportId) {
  return viewportReferenceLineDraggableRotatable.includes(viewportId)
}

function getReferenceLineSlabThicknessControlsOn(viewportId) {
  return viewportReferenceLineSlabThicknessControlsOn.includes(viewportId)
}


const activeViewportIdRef = ref(viewportId1)
const toolGroups = []

function createToolGroups() {
  for (let i = 0; i < seriesCount; i++) {
    const mprToolGroupId = 'mprToolGroupId' + i
    const renderingEngineId = `renderingEngineId-${i}`
    const toolGroup = ToolGroupManager.createToolGroup(mprToolGroupId)
    toolGroup.addTool(PanTool.toolName)
    toolGroup.addTool(ZoomTool.toolName)
    toolGroup.addTool(StackScrollMouseWheelTool.toolName)
    toolGroup.addTool(CrosshairsTool.toolName, {
      getReferenceLineColor,
      getReferenceLineControllable,
      getReferenceLineDraggableRotatable,
      getReferenceLineSlabThicknessControlsOn
    })


    toolGroups.push(toolGroup)
    viewportIds.forEach((viewportId, i) => {
      toolGroup.addViewport(viewportId, renderingEngineId)
    })

    toolGroup.setToolActive(PanTool.toolName, {
      bindings: [{ mouseButton: MouseBindings.Auxiliary }]
    })

    toolGroup.setToolActive(ZoomTool.toolName, {
      bindings: [{ mouseButton: MouseBindings.Secondary }]
    })

    toolGroup.setToolActive(StackScrollMouseWheelTool.toolName)


    toolGroup.setToolActive(CrosshairsTool.toolName, {
      bindings: [{ mouseButton: MouseBindings.Primary }]
    })
  }

  // Set the tool group on the viewport. Add only the first three viewports
  // because crosshairs can work with up to three viewports

}

const load = async () => {
  await createVolume()
  initViewports()
  createToolGroups()
  for (let i = 0; i < seriesCount; i++) {
    volumes[i].load()
    renderingEngines[i].renderViewports(viewportIds)
  }
}

onMounted(async () => {
  await initDemo()
  cache.setMaxCacheSize(4 * 1024 * 1024 * 1024)
  load()
})
let index = 0
let handler
const play = () => {
  renderingEngines[index].renderViewports(viewportIds)
  if (index < seriesCount - 1) {
    index++
  } else {
    index = 0
  }
  handler = setTimeout(play, 300)
}
const pause = () => {
  if (handler) {
    clearTimeout(handler)
  }
}
</script>

<template>
  <div class="w-full max-w-[900px] ml-auto mr-auto h-[500px] grid grid-cols-2 grid-rows-2 border-2 border-amber-200">
    <template v-for="view in views" :key="view.class">
      <div
        :class="[view.class, activeViewportIdRef === view.viewportId ? ' border-amber-500': 'border-transparent']"
        @click="activeViewportIdRef === view.viewportId"
        :ref="view.ref">
      </div>
    </template>
  </div>
  <button @click="play" class="mr-[20px]">play</button>
  <button @click="pause">pause</button>
</template>

<style scoped>

</style>
